home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UMacAppGlobals.cp < prev    next >
Text File  |  1991-05-01  |  21KB  |  906 lines

  1. // UMacAppGlobals.cp 
  2. // Copyright © 1984-1991 by Apple Computer Inc. All rights reserved.
  3.  
  4. #include "UMacAppGlobals.h"
  5.  
  6. #ifndef __ULIST__
  7. #include <UList.h>
  8. #endif
  9.  
  10. #ifndef __APPLEEVENTS__
  11. #include <AppleEvents.h>
  12. #endif
  13.  
  14. #ifndef __EDITIONS__
  15. #include <Editions.h>
  16. #endif
  17.  
  18. #ifndef __UAPPLEEVENTS__
  19. #include <UAppleEvents.h>
  20. #endif
  21.  
  22. #ifndef __UEVENT__
  23. #include <UEvent.h>
  24. #endif
  25.  
  26. #ifndef __UCOMMAND__
  27. #include <UCommand.h>
  28. #endif
  29.  
  30. #ifndef __UDESIGNATOR__
  31. #include <UDesignator.h>
  32. #endif
  33.  
  34. #ifndef __UEVTHANDLER__
  35. #include <UEvtHandler.h>
  36. #endif
  37.  
  38. #ifndef __UAPPLICATION__
  39. #include <UApplication.h>
  40. #endif
  41.  
  42. #ifndef __UDOCUMENT__
  43. #include <UDocument.h>
  44. #endif
  45.  
  46. #ifndef __UFILEBASEDDOCUMENT__
  47. #include <UFileBasedDocument.h>
  48. #endif
  49.  
  50. #ifndef __UPRINTHANDLER__
  51. #include <UPrintHandler.h>
  52. #endif
  53.  
  54. #ifndef __BALLOONS__
  55. #include <Balloons.h>
  56. #endif
  57.  
  58. #ifndef __UVIEW__
  59. #include <UView.h>
  60. #endif
  61.  
  62. #ifndef __UADORNERS__
  63. #include <UAdorners.h>
  64. #endif
  65.  
  66. #ifndef __UWINDOW__
  67. #include <UWindow.h>
  68. #endif
  69.  
  70. #ifndef __CONTROLS__
  71. #include <Controls.h>
  72. #endif
  73.  
  74. #ifndef __UCONTROL__
  75. #include <UControl.h>
  76. #endif
  77.  
  78. #ifndef __USCROLLER__
  79. #include <UScroller.h>
  80. #endif
  81.  
  82. #ifndef __UMACAPPUTILITIES__
  83. #include <UMacAppUtilities.h>
  84. #endif
  85.  
  86. #ifndef __UERRORMGR__
  87. #include <UErrorMgr.h>
  88. #endif
  89.  
  90. #ifndef __UMEMORY__
  91. #include <UMemory.h>
  92. #endif
  93.  
  94. #ifndef __ERRORS__
  95. #include <Errors.h>
  96. #endif
  97.  
  98. #ifndef __TOOLUTILS__
  99. #include <ToolUtils.h>
  100. #endif
  101.  
  102. #ifndef __UBUSYCURSOR__
  103. #include <UBusyCursor.h>
  104. #endif
  105.  
  106. #ifndef __UDEBUG__
  107. #include <UDebug.h>
  108. #endif
  109.  
  110. #ifndef __UINSPECTOR__
  111. #include <UInspector.h>
  112. #endif
  113.  
  114. #ifndef __UDEPENDENCIES__
  115. #include <UDependencies.h>
  116. #endif
  117.  
  118. #ifndef __MENUS__
  119. #include <Menus.h>
  120. #endif
  121.  
  122. #ifndef __UMENUMGR__
  123. #include <UMenuMgr.h>
  124. #endif
  125.  
  126. #ifndef __SCRAP__
  127. #include <Scrap.h>
  128. #endif
  129.  
  130. #ifndef __UCLIPBOARDMGR__
  131. #include <UClipboardMgr.h>
  132. #endif
  133.  
  134. #ifndef __UDESKSCRAPVIEW__
  135. #include <UDeskScrapView.h>
  136. #endif
  137.  
  138. #ifndef __USYNCHSCROLLER__
  139. #include <USynchScroller.h>
  140. #endif
  141.  
  142. #ifndef __RESOURCES__
  143. #include <Resources.h>
  144. #endif
  145.  
  146. #ifndef __FONTS__
  147. #include <Fonts.h>
  148. #endif
  149.  
  150. #ifndef __PACKAGES__
  151. #include <Packages.h>
  152. #endif
  153.  
  154. #ifndef __SCRIPT__
  155. #include <Script.h>
  156. #endif
  157.  
  158. #ifndef __DEVICES__
  159. #include <Devices.h>
  160. #endif
  161.  
  162. #ifndef __STDIO__
  163. #include <StdIO.h>
  164. #endif
  165.  
  166. //--------------------------------------------------------------------------------------------------
  167. TextStyle gApplicationStyle;
  168. Boolean gCouldPrint;
  169.  
  170. #if qExperimentalAndUnsupported
  171. Boolean gEnableDoubleBuffering = TRUE;
  172. #endif
  173.  
  174. Boolean gOldChooserFlag;
  175. TDynamicArray* gSignatures;
  176. TextStyle gSystemStyle;
  177. WindowPtr gWorkPort;
  178. RgnHandle gTempRgn;
  179. RgnHandle gTempRgn2;
  180.  
  181. #if qDebug
  182. Boolean gBusyTempRgn = FALSE;
  183. Str255 gUsedBy = "";
  184. Boolean gBusyTempRgn2 = FALSE;
  185. Str255 gUsedBy2 = "";
  186. #endif
  187.  
  188. StringHandle pCopyright;
  189. TrapPatch pETSPatch;
  190. FailInfo pFi;
  191.  
  192. //--------------------------------------------------------------------------------------------------
  193. #pragma segment MAGlobalsRes
  194.  
  195. // Retrieve the title of the button control. If itemNo isn't a button, then return ''.
  196. pascal void GetAlertButtonTitle(DialogPtr theDialog, short itemNo, Str255& theTitle)
  197. {
  198.     short itemType;
  199.     Handle item;
  200.     Rect box;
  201.  
  202.     theTitle = "";
  203.     GetDItem(theDialog, itemNo, itemType, item, box);
  204.     if (itemType == (ctrlItem + btnCtrl))
  205.         GetCTitle((ControlHandle)item, theTitle);
  206. }
  207.  
  208. //--------------------------------------------------------------------------------------------------
  209. #pragma segment MAGlobalsRes
  210.  
  211. // Handle a keypress that has been mapped to one of the button controls. 
  212. pascal void DoAlertKeyDown(DialogPtr theDialog, short itemNo)
  213. {
  214.     short itemType;
  215.     Handle item;
  216.     Rect box;
  217.     long finalTicks;
  218.  
  219.     GetDItem(theDialog, itemNo, itemType, item, box);
  220.     if (itemType == (ctrlItem + btnCtrl))
  221.     {
  222.         // this code gives visual feedback 
  223.         HiliteControl((ControlHandle)item, inButton);    // hilite the button 
  224.         Delay(8, finalTicks);                            // delay for 8 ticks 
  225.         HiliteControl((ControlHandle)item, 0);            // stop hiliting the button 
  226.     }
  227. }
  228.  
  229. //--------------------------------------------------------------------------------------------------
  230. #pragma segment MAGlobalsRes
  231.  
  232. pascal Boolean CompareAlertKeysToItem(DialogPtr theDialog, Str31& theChars, short& itemHit)
  233. // Compares the buffered multi-byte chars to the first character of each button title
  234. // 1st button in alert (by convention == "OK").  2nd button in alert 
  235. // (by convention == "Cancel").    3rd button in alert (by convention == "No")
  236. {
  237.     Str255 title;
  238.     
  239.     GetAlertButtonTitle(theDialog, ok, title);
  240.     if (CompareMultiByteChars(theChars, title, FALSE))
  241.     {
  242.         itemHit = ok;
  243.         return TRUE;
  244.     }
  245.     
  246.     GetAlertButtonTitle(theDialog, cancel, title);
  247.     if (CompareMultiByteChars(theChars, title, FALSE))
  248.     {
  249.         itemHit = cancel;
  250.         return TRUE;
  251.     }
  252.     
  253.     GetAlertButtonTitle(theDialog, kNoButton, title);
  254.     if (CompareMultiByteChars(theChars, title, FALSE))
  255.     {
  256.         itemHit = kNoButton;
  257.         return TRUE;
  258.     }
  259.     return FALSE;
  260. }
  261.  
  262. //--------------------------------------------------------------------------------------------------
  263. #pragma segment MAGlobalsRes
  264.  
  265. pascal Boolean MacAppAlertFilter(DialogPtr theDialog,
  266.                                  EventRecord& theEvent,
  267.                                  short& itemHit)
  268.  
  269. {
  270.     if (gApplication)
  271.         return gApplication->AlertFilter(theDialog, theEvent, itemHit);
  272.     else
  273.         return FALSE;                            //???
  274. }
  275.  
  276. //--------------------------------------------------------------------------------------------------
  277. #pragma segment MAGlobalsRes
  278.  
  279. pascal void ApplicationBeep(void)
  280.  
  281. {
  282.     if (gApplication)
  283.         gApplication->Beep(2);
  284.     else
  285.         SysBeep(2);
  286. }
  287.  
  288. //--------------------------------------------------------------------------------------------------
  289. #pragma segment MAGlobalsRes
  290. /*$Push*/
  291. #if qTrace
  292. /*$D+*/
  293. #endif
  294.  
  295. pascal void CleanupMacApp(void)
  296.  
  297. {
  298.     long OldA5 = SetCurrentA5();                // ***** Called from trap patches *****
  299.  
  300.     SetResLoad(TRUE);                            // Make sure segments can load 
  301.  
  302.     UnpatchTrap(pETSPatch);                        // Guaranteed not to fail 
  303.  
  304.     if (gApplication)
  305.         gApplication->Terminate();
  306.  
  307.     gBusyCursor = (TBusyCursor *)FreeIfObject(gBusyCursor);
  308.  
  309.     if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr)
  310.         AEDisposeDesc(gServerAddress);
  311.  
  312. #if qDebug
  313.     DebugTerminate();
  314. #endif
  315.  
  316.     UnpatchAll();
  317.  
  318.     SetChooserAlert(gOldChooserFlag);
  319.  
  320.     SetA5(OldA5);
  321. }
  322. //$Pop
  323.  
  324. //--------------------------------------------------------------------------------------------------
  325. #if qDebug
  326. #pragma segment MADebug
  327. /*$Push*/
  328. #if qTrace
  329. /*$D+*/
  330. #endif
  331.  
  332. pascal void DoneWithTempRgn(void)
  333. /* Indicates that gTempRgn is no longer in use. Call this only if qDebug
  334.   is true. */
  335.  
  336. {
  337.     if (!gBusyTempRgn)
  338.         ProgramBreak("DoneWithTempRgn called, but gTempRgn is not locked");
  339.     gBusyTempRgn = FALSE;
  340.     gUsedBy = "";
  341.     SetEmptyRgn(gTempRgn);
  342. }
  343. //$Pop
  344. #endif
  345.  
  346. //--------------------------------------------------------------------------------------------------
  347. #if qDebug
  348. #pragma segment MADebug
  349. /*$Push*/
  350. #if qTrace
  351. /*$D+*/
  352. #endif
  353.  
  354. pascal void DoneWithTempRgn2(void)
  355. /* Indicates that gTempRgn2 is no longer in use. Call this only if qDebug
  356.   is true. */
  357.  
  358. {
  359.     if (!gBusyTempRgn2)
  360.         ProgramBreak("DoneWithTempRgn2 called, but gTempRgn2 is not locked");
  361.     gBusyTempRgn2 = FALSE;
  362.     gUsedBy2 = "";
  363.     SetEmptyRgn(gTempRgn2);
  364. }
  365. //$Pop
  366. #endif
  367.  
  368. //--------------------------------------------------------------------------------------------------
  369. #if qDebug
  370. #pragma segment MADebug
  371.  
  372. pascal void EntDebugger(Boolean entering)
  373.  
  374. {
  375.     if (gBusyCursor)
  376.         gBusyCursor->Activate(!entering);
  377. }
  378. #endif
  379.  
  380. //--------------------------------------------------------------------------------------------------
  381. #pragma segment MADebug
  382.  
  383. pascal long LookupSymbol(Str255& sym)
  384.  
  385. {
  386.     if (gInitialized)
  387.         return (gApplication->GetTarget())->LookupSymbol(sym);
  388.     else
  389.         return -1;
  390. }
  391.  
  392. //--------------------------------------------------------------------------------------------------
  393. #pragma segment MATerminate
  394.  
  395. pascal void ExitMacApp(void)
  396.  
  397. {
  398.     CleanupMacApp();
  399.     ExitToShell();
  400. }
  401.  
  402. //--------------------------------------------------------------------------------------------------
  403. #pragma segment MAGlobalsRes
  404.  
  405. pascal WindowPtr FreeIfWMgrWindow(WindowPtr w,
  406.                                   Boolean dispose)
  407.  
  408. {
  409.     if (w)
  410.     {
  411.         if (dispose)
  412.         {
  413.             if (w == qd.thePort)                /* Only need to invalidate focus if freed
  414.                                                   window is the current port */
  415.             {
  416.                 if (gApplication)
  417.                     gApplication->InvalidateFocus();
  418.                 SetPort(gWorkPort);
  419.             }
  420.             DisposeWindow(w);
  421.         }
  422.         else
  423.             CloseWindow(w);
  424.     }
  425.     return NULL;                                // convenience to caller 
  426. }
  427.  
  428. //--------------------------------------------------------------------------------------------------
  429. #pragma segment MAGlobalsRes
  430.  
  431. pascal DialogPtr GetNewCenteredDialog(short dialogID,
  432.                                       Ptr dStorage,
  433.                                       WindowPtr behind)
  434.  
  435. {
  436.     DialogTHndl dlogTemplate;
  437.  
  438.     SetCursor(qd.arrow);
  439.     if (gApplication)
  440.         gApplication->InvalidateMouseRegions();
  441.     dlogTemplate = (DialogTHndl)GetResource('DLOG', dialogID);
  442.     if (dlogTemplate)
  443.     {
  444.         CenterRectOnScreen((*dlogTemplate)->boundsRect, TRUE, TRUE, TRUE);
  445.         return GetNewDialog(dialogID, dStorage, behind);
  446.     }
  447.     else
  448.     {
  449.         SysBeep(2);                                // At least give some indication 
  450. #if qDebug
  451.         Str255 theString;
  452.         ConcatNumber("Unable to find ‘DLOG’ resource ", dialogID, theString);
  453.         ProgramBreak(theString);
  454. #endif
  455.  
  456.     }
  457.     return NULL;
  458. }
  459.  
  460. //--------------------------------------------------------------------------------------------------
  461. // Really a utility but, the gWorkPort isn't reachable from UMacAppUtilities
  462. #pragma segment MAUtilitiesRes
  463.  
  464. pascal void GetTextStyleFontInfo(const TextStyle& theTextStyle,
  465.                                  FontInfo& theFontInfo,
  466.                                  short& theFontHeight)
  467.  
  468. {
  469.     GrafPtr savedPort;
  470.  
  471.     GetPort(savedPort);
  472.     SetPort(gWorkPort);
  473.     SetPortTextStyle(theTextStyle);
  474.     theFontHeight = MAGetFontInfo(theFontInfo);
  475.     SetPort(savedPort);
  476. }
  477.  
  478. //--------------------------------------------------------------------------------------------------
  479. // Must be in the init segment; unloaded at start of event loop
  480. #pragma segment MAInit
  481.  
  482. pascal void DoInitUMacApp(void)
  483.  
  484. {
  485.     // Initialize runtime support for objects 
  486.     InitUObject();
  487. #if qDebug
  488.     InitUDebug(NULL, NULL, (Ptr) & EntDebugger, (Ptr) & LookupSymbol);
  489. #endif
  490. #if qInspector
  491.     InitUInspector();
  492. #endif
  493.  
  494. #if qDebug
  495.     gTraceSetupMenus = FALSE;
  496. #endif
  497.  
  498.     gOrthogonal[vSel] = hSel;
  499.     gOrthogonal[hSel] = vSel;
  500.  
  501.     gPrinting = FALSE;
  502.     gCurrPrintHandler = NULL;
  503.     gDrawingPictScrap = FALSE;
  504.     gDrawingPictScrapView = NULL;
  505.  
  506.     gNumUntitled = 1;                            // call the first document Untitled-1 
  507.  
  508.     gErrorParm3 = "";
  509.     gFocusedView = NULL;
  510.  
  511.     SetTextStyle(gSystemStyle, systemFont, normal, GetDefFontSize(), gRGBBlack);
  512.     SetTextStyle(gApplicationStyle, applFont, normal, 0, gRGBBlack);
  513.  
  514.     FailOSErr(HeadPatch(pETSPatch, _ExitToShell, (Ptr) & CleanupMacApp));
  515.  
  516.     pCopyright = NewString(kCopyright);
  517.  
  518.     // Other 1-time initialization 
  519.     gTempRgn = MakeNewRgn();
  520.     gTempRgn2 = MakeNewRgn();
  521.  
  522.     gWResSignature = kNoIdentifier;
  523.     gWResType = "";
  524.  
  525.     // Create a work port for our convenience 
  526.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  527.         gWorkPort = NewCWindow(NULL, gZeroRect, "", FALSE, documentProc, NULL, FALSE, 0);
  528.     else
  529.         gWorkPort = NewWindow(NULL, gZeroRect, "", FALSE, documentProc, NULL, FALSE, 0);
  530.  
  531.     gStdHysteresis = Point(4,4);                        // ??? any better choice ??? 
  532.  
  533.     {
  534.         Rect theGrayRect((*GetGrayRgn())->rgnBBox);
  535.  
  536.         gStdWMoveBounds = theGrayRect;
  537.         gStdWMoveBounds.Inset(Point(4, 4));
  538.     
  539.         // arbitrary minimum size; maximum size is grayRgn size minus half the title bar
  540.         gStdWSizeRect = Rect(Point(80, 80), Point(theGrayRect.Length(vSel) - 8, theGrayRect.Length(hSel)));
  541.     
  542.         gStdWScreenRect = theGrayRect;
  543.         gStdWScreenRect.Inset(Point(16, 16));
  544.     }
  545.  
  546.     InitUBusyCursor();
  547.  
  548.     gNullPrintHandler = new TPrintHandler;
  549.     gNullPrintHandler->IPrintHandler(NULL);
  550.  
  551.     gPrintHandler = gNullPrintHandler;
  552.  
  553.     gOldChooserFlag = SetChooserAlert(FALSE);
  554.  
  555.     // Create the signature lists.
  556.     gSignatures = new TDynamicArray;
  557.     gSignatures->IDynamicArray(kEmptyIndex, sizeof(SignatureRec));
  558.  
  559.     if (qTemplateViews)
  560.     {
  561.         // =============================================== 
  562.         // Suppress Linker dead stripping of these classes 
  563.  
  564.         if (gDeadStripSuppression)
  565.         {
  566.             DontDeadStrip(TView);
  567.             DontDeadStrip(TWindow);
  568.             DontDeadStrip(TScrollBar);
  569.             DontDeadStrip(TScrollerScrollBar);
  570.             DontDeadStrip(TScroller);
  571.             DontDeadStrip(TPrimaryScroller);
  572.             DontDeadStrip(TSecondaryScroller);
  573.             DontDeadStrip(TSynchScroller);
  574.             DontDeadStrip(TDeskScrapView);
  575.             DontDeadStrip(TFileBasedDocument);
  576.             DontDeadStrip(TNoChangesCommand);
  577.             DontDeadStrip(TList);
  578.         }
  579.         // =============================================== 
  580.  
  581.         RegisterStdType("TView", kStdView);
  582.         RegisterStdType("TView", kStdDefaultView);
  583.         RegisterStdType("TWindow", kStdWindow);
  584.         RegisterStdType("TScrollerScrollBar", kStdSScrollBar);
  585.         RegisterStdType("TScroller", kStdScroller);
  586.  
  587.         RegisterStdType("TFileBasedDocument", kStdDocument);
  588.         RegisterStdType("TNoChangesCommand", kStdTracker);
  589.         RegisterStdType("TList", kStdList);
  590.     }
  591.  
  592.     InitUAdorners();                            // Temporarily needed for debug window 
  593. #if qDebug
  594.     TrcEnable(TRUE); 
  595. #endif
  596.  
  597.     InitUDesignator();                            // registers designator's std types 
  598.     InitUMenuMgr();
  599.     InitUClipboardMgr();
  600.     InitUAppleEvents();
  601. }
  602.  
  603. //--------------------------------------------------------------------------------------------------
  604. #pragma segment MARes
  605.  
  606. pascal void InstallIfPrintHandler(TPrintHandler* aPrintHandler,
  607.                                   TView* aView)
  608.  
  609. {
  610.     TPrintHandler * aNewPrintHandler;
  611.  
  612.     if ((aPrintHandler) && (aView) && (aPrintHandler != gNullPrintHandler) && (gPrintHandler != gNullPrintHandler))
  613.     {
  614.         aNewPrintHandler = (TPrintHandler *)aPrintHandler->Clone();    // signals failure if can't clone
  615.         aNewPrintHandler->fView = aView;
  616.         aNewPrintHandler->SetDefaultPrintInfo();
  617.         if (aView->fDocument)
  618.             aView->fDocument->AttachPrintHandler(aNewPrintHandler);
  619.         aView->AttachPrintHandler(aNewPrintHandler);
  620.     }
  621. }
  622.  
  623. //--------------------------------------------------------------------------------------------------
  624. #pragma segment MAGlobalsRes
  625.  
  626. pascal RgnHandle MakeNewRgn(void)
  627.  
  628. {
  629.     RgnHandle aRgn = NewRgn();
  630.     FailNIL(aRgn);
  631.     return aRgn;
  632. }
  633.  
  634. //--------------------------------------------------------------------------------------------------
  635. #pragma segment MAOpen
  636.  
  637. pascal ObjClassID DetermineClassID(IDType signature,
  638.                             const MAName& className)
  639. {
  640.     if (className.IsEmpty())
  641.         return GetClassIDFromSignature(signature);    
  642.     else
  643.         return GetClassIDFromName(className);    
  644. }
  645.  
  646. //--------------------------------------------------------------------------------------------------
  647. #pragma segment MAOpen
  648.  
  649. pascal Boolean NewStdObjectTestElement(ArrayIndex elementIndex,
  650.                                        void* staticLink)
  651.  
  652. {
  653.     return (((SignatureRecPtr)(gSignatures->ComputeAddress(elementIndex)))->itsSignature == *((IDType *)staticLink));
  654. }
  655.  
  656. pascal ObjClassID GetClassIDFromSignature(IDType signature)
  657. {
  658.     ArrayIndex i;
  659.  
  660.     i = gSignatures->EachElementDoTil(NewStdObjectTestElement, &signature, kIterateForward);
  661.     if (i != kEmptyIndex)
  662.         return ((ObjClassID)((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsClassID);
  663.     else
  664.         return kNilClass;
  665. }
  666.  
  667. //--------------------------------------------------------------------------------------------------
  668. #pragma segment MAOpen
  669.  
  670. pascal TObject* NewStdObject(IDType signature)
  671.  
  672. {
  673.     ObjClassID classID = GetClassIDFromSignature(signature);
  674.  
  675.     if (classID != kNilClass)
  676.         return NewObjectByClassId(classID);
  677.     else
  678.     {
  679.         if (qDebug)
  680.         {
  681.             fprintf(stderr, "signature=‘%4s’\n", (char *) &signature);
  682.             ProgramBreak("Unable to find class for the given signature");
  683.         }
  684.         Failure(errMissingSignature, 0);    
  685.     }
  686. }
  687.  
  688. // old version is below
  689. #if FALSE
  690. pascal TObject* NewStdObject(IDType signature)
  691.  
  692. {
  693.     ArrayIndex i;
  694.  
  695.     i = gSignatures->EachElementDoTil(NewStdObjectTestElement, &signature, kIterateForward);
  696.     if (i != kEmptyIndex)
  697.         return NewObjectByClassId((ObjClassID)((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsClassID);
  698.     else
  699.     {
  700.         if (qDebug)
  701.         {
  702.             fprintf(stderr, "signature=‘%4s’\n", (char *) &signature);
  703.             ProgramBreak("Unable to find class for the given signature");
  704.         }
  705.         Failure((short) memFullErr, 0);    
  706.     }
  707. }
  708. #endif
  709.  
  710. //--------------------------------------------------------------------------------------------------
  711. #pragma segment MAOpen
  712.  
  713. pascal TObject* NewObjectBySignature(IDType signature,
  714.                                         const MAName& className)
  715.  
  716. {
  717.     if (className.IsEmpty())
  718.     {
  719.         return NewStdObject(signature);
  720.     }
  721.     else
  722.     {
  723.         return NewObjectByClassName(className);
  724.     }
  725. }
  726.  
  727. //--------------------------------------------------------------------------------------------------
  728. #pragma segment MAGlobalsRes
  729.  
  730. short FindPos(const Str255& pattern,
  731.                      Str255& source)
  732.  
  733. {
  734.     short i = 0;
  735.     short j = 0;
  736.     short position = 0;
  737.  
  738.     do
  739.     {
  740.         ++i;
  741.         position = i;
  742.         for (j = 1; j <= pattern.Length(); ++j)
  743.             if (!((source[i + j - 1] == pattern[j]) && (CharByte((Ptr) & source, i + j) == 0)))
  744.             {
  745.                 position = 0;
  746.                 break;
  747.             }
  748.     } while (!((position > 0) || (i >= source.Length() - pattern.Length() + 1)));
  749.  
  750.     return position;
  751. }
  752.  
  753.  
  754. pascal Boolean ParseTitleTemplate(Str255& itsTemplate,
  755.                                   short& preDocname,
  756.                                   short& constTitle)
  757.  
  758. {
  759.     const Str255 kPreDocname = "<<<";
  760.     const short kPreSize = 3;
  761.     const Str255 kPostDocname = ">>>";
  762.     const short kPostSize = 3;
  763.  
  764.     if (itsTemplate.IsEmpty())
  765.     {
  766.         preDocname = 1;
  767.         constTitle = 0;
  768.     }
  769.     else
  770.     {
  771.         preDocname = FindPos(kPreDocname, itsTemplate);
  772.         if (preDocname > 0)
  773.         {
  774.             itsTemplate.Delete(preDocname, kPreSize);
  775.  
  776.             short x = FindPos(kPostDocname, itsTemplate);
  777.             if (x == 0)
  778.                 constTitle = preDocname - 1;
  779.             else
  780.             {
  781.                 itsTemplate.Delete(x, kPostSize);
  782.                 constTitle = itsTemplate.Length() - x + preDocname;
  783.             }
  784.         }
  785.     }
  786.  
  787.     return preDocname > 0;
  788. }
  789.  
  790. //--------------------------------------------------------------------------------------------------
  791. #pragma segment MAGlobalsRes
  792.  
  793. pascal Boolean RegisterStdTypeTestElement(ArrayIndex elementIndex,
  794.                                           void* staticLink)
  795.  
  796. {
  797.     return (((SignatureRecPtr)(gSignatures->ComputeAddress(elementIndex)))->itsSignature == *((IDType *)staticLink));
  798. }
  799.  
  800.  
  801. pascal void RegisterStdType(const Str255& typeName,
  802.                             IDType signature)
  803. // Register or re-register a type and a class 
  804.  
  805. {
  806.     ArrayIndex i;
  807.     SignatureRec itsSignatureRec;
  808.  
  809.     // If the name can't be found it was probably misspelled or dead-stripped 
  810.     itsSignatureRec.itsSignature = signature;
  811.     itsSignatureRec.itsClassID = GetClassIDFromName(typeName);
  812.     if (itsSignatureRec.itsClassID == kNilClass)
  813.         Failure(minErr, 0);                        //??? need to assign a message???
  814.  
  815.     // Replace or add signature as necessary 
  816.     i = gSignatures->EachElementDoTil(RegisterStdTypeTestElement, &signature, kIterateForward);
  817.     if (i != kEmptyIndex)
  818.         *((SignatureRecPtr)(gSignatures->ComputeAddress(i))) = itsSignatureRec;
  819.     else
  820.         gSignatures->InsertElementsBefore(gSignatures->GetSize() + 1, (Ptr) & itsSignatureRec, 1);
  821. }
  822.  
  823. //--------------------------------------------------------------------------------------------------
  824. #pragma segment MAGlobalsRes
  825.  
  826. pascal Boolean SubstituteInTitle(Str255& title,
  827.                                  const Str255& newStuff,
  828.                                  short preDocname,
  829.                                  short constTitle)
  830.  
  831. {
  832.     if (preDocname > 0)
  833.     {
  834.         if (constTitle == 0)
  835.             title = newStuff;
  836.         else
  837.         {
  838.             title.Delete(preDocname, title.Length() - constTitle);
  839.             title.Insert(newStuff, preDocname);
  840.         }
  841.         return TRUE;
  842.     }
  843.     else
  844.         return FALSE;
  845. }
  846.  
  847. //--------------------------------------------------------------------------------------------------
  848. #if qDebug
  849. #pragma segment MADebug
  850. /*$Push*/
  851. #if qTrace
  852. /*$D+*/
  853. #endif
  854.  
  855. pascal void UseTempRgn(const Str255& byWhom)
  856. /* Call this when you are about to use gTempRgn and qDebug is true. Used
  857.   with DoneWithTempRgn will prevent you from trying to use gTempRgn
  858.   from two places at the same time. */
  859.  
  860. {
  861.     if (gBusyTempRgn)
  862.     {
  863.         fprintf(stderr, "‘%s’ is trying to lock gTempRgn,", (char *) byWhom);
  864.         fprintf(stderr, "but it is already locked by ‘%s’\n", (char *) gUsedBy);
  865.         ProgramBreak("Error in UseTempRgn");
  866.     }
  867.     else
  868.     {
  869.         gBusyTempRgn = TRUE;
  870.         gUsedBy = byWhom;
  871.     }
  872. }
  873. //$Pop
  874. #endif
  875.  
  876. //--------------------------------------------------------------------------------------------------
  877. #if qDebug
  878. #pragma segment MADebug
  879. /*$Push*/
  880. #if qTrace
  881. /*$D+*/
  882. #endif
  883.  
  884. pascal void UseTempRgn2(const Str255& byWhom)
  885. /* Call this when you are about to use gTempRgn2 and qDebug is true. Used
  886.   with DoneWithTempRgn2 will prevent you from trying to use gTempRgn2
  887.   from two places at the same time. */
  888.  
  889. {
  890.     if (gBusyTempRgn2)
  891.     {
  892.         fprintf(stderr, "‘%s’ is trying to lock gTempRgn2,", (char *) byWhom);
  893.         fprintf(stderr, "but it is already locked by ‘%s’\n", (char *) gUsedBy);
  894.         ProgramBreak("Error in UseTempRgn2");
  895.     }
  896.     else
  897.     {
  898.         gBusyTempRgn2 = TRUE;
  899.         gUsedBy2 = byWhom;
  900.     }
  901. }
  902. //$Pop
  903. #endif
  904.  
  905.  
  906.